package com.uwlaser.webservice.client;

import com.alibaba.fastjson.JSONObject;
import com.uwlaser.webservice.exception.WebServiceCodeErrorException;
import com.uwlaser.webservice.exception.WebServiceResultErrorException;
import com.uwlaser.webservice.exception.WebServiceTimeoutException;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.dom4j.DocumentException;
import java.nio.charset.Charset;


/**
 * @Author QZK
 * @Description TODO
 * @Date 2022-11-23-16:33
 * @Version 1.0
 */
public class WsdlSendRequest {

    /**
     * 发送请求
     * @param resolve
     * @param methodName
     * @param bodyParams
     * @param headerParams
     * @return
     * @throws DocumentException
     */
    public static JSONObject sendRequest(WsdlEntity resolve,String methodName, String bodyParams, String headerParams) throws Exception {
        //获取方法实体
        WsdlMethodEntity methodEntity = resolve.getMethodEntity(methodName);

        //获取XML
        String xmlContent = WsdlResolver.getXmlContent(methodEntity, methodName, bodyParams, headerParams);

        // 通过HttpClient发送请求，如果是SOAP1.2 则需要传 SOAPAction，固定写法 http://WebXml.com.cn/getDomesticCity
        String returnDatabase = doPostSoap(resolve.getUrl(),xmlContent,methodEntity.getVersion().equals(WsdlMethodEntity.SOAP12_SIGN) ? "http://WebXml.com.cn/getDomesticCity" : null);

        if (returnDatabase == null){
            throw new WebServiceResultErrorException("解析服务器返回的XML错误,错误信息：服务器返回空数据！");
        }
        if(returnDatabase.indexOf("未将对象引用设置到对象的实例") != -1 ){
            WebServiceCodeErrorException exception = new WebServiceCodeErrorException("解析服务器返回的XML错误,错误信息：服务器无法处理请求。 ---> 未将对象引用设置到对象的实例，可能是因为组装的XML不符合服务器要求，或者JSON转XML时大小写问题引起的：组装的XML：" + xmlContent);
            exception.setRequestResult(returnDatabase);
            throw exception;
        }

        //把xml转为JSON对象
        JSONObject jsonObject = null;
        try {
            // 将请求结果转换成json类型
            jsonObject = WsdlResolver.xml2Json(returnDatabase);
        } catch (Exception e) {
            WebServiceCodeErrorException exception = new WebServiceCodeErrorException("解析服务器返回的XML失败,错误信息：" + e.getMessage() + "，服务器返回XML：" + returnDatabase);
            exception.setRequestResult(returnDatabase);
            throw exception;
        }
        return jsonObject;
    }

    private static String doPostSoap(String url, String soap, String SOAPAction) throws Exception {
        //请求体
        String retStr = "";
        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");

            if(SOAPAction != null){
                httpPost.setHeader("SOAPAction", SOAPAction);
            }
            StringEntity data = new StringEntity(soap, Charset.forName("UTF-8"));
            httpPost.setEntity(data);
            CloseableHttpResponse response = closeableHttpClient
                    .execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                // 打印响应内容
                retStr = EntityUtils.toString(httpEntity, "UTF-8");
            }
        } catch (Exception e) {
            throw new WebServiceTimeoutException("发送WebService请求失败，URL【"+url+"】，错误信息："+e.getMessage());
        } finally {
            // 释放资源
            try {
                if(closeableHttpClient != null){
                    closeableHttpClient.close();
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        return retStr;
    }

}
